package com.mmall.concurrency.example.aqs;

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

/**
 * Created by RID on 2018/4/15.
 */
@Slf4j
public class ForkJoinTaskExample2 extends RecursiveTask<Integer> {

    private int start;
    private int end;
    private long lauch;
    private long done;
    private final static int threshold=2;

    public ForkJoinTaskExample2(int start, int end) {
        this.start = start;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        int sum =0;

        boolean split = end-start<=threshold;
        if (split){
            for (int i=start; i<=end; i++){
                sum+=i;
            }
        }else {
            int middle=(start+end)/2;
            ForkJoinTaskExample2 leftTask=new ForkJoinTaskExample2(start,middle);
            ForkJoinTaskExample2 rightTask=new ForkJoinTaskExample2(middle+1,end);

            //执行子任务
            leftTask.fork();
            rightTask.fork();

            //合并计算结果
            int reult = leftTask.join()+ rightTask.join();
            sum=reult;

        }

        return sum;
    }

    public Integer iterativeCompute(){

        lauch=System.nanoTime();
        int sum=0;
        for (int t= start; t<=end; t++)
            sum+=t;
        done=System.nanoTime();
        log.info("Iterative Computing takes {} ws", TimeUnit.NANOSECONDS.toMicros(done-lauch));
        return sum;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool pool= new ForkJoinPool();

        ForkJoinTaskExample2 task= new ForkJoinTaskExample2(1,10000000);

        long lauch=System.nanoTime();
        //执行计算任务
        Future<Integer> compute= pool.submit(task);

        //获取结果
        long done=System.nanoTime();
        int result= compute.get();
        log.info("ForkJoin Computing takes {} ws", TimeUnit.NANOSECONDS.toMicros(done-lauch));
        task.iterativeCompute();
    }

}
